home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / libs / sphigs / sph_mac.hqx / SRGP port to 5.0 (compressed) / SRGP_SPHIGS Root / MacSPHIGS / MAT3vec.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-02-13  |  4.1 KB  |  141 lines

  1. /* Copyright 1988, Brown Computer Graphics Group.  All Rights Reserved. */
  2.  
  3. /* --------------------------------------------------------------------------
  4.  * This file contains routines that operate on matrices and vectors, or
  5.  * vectors and vectors.
  6.  * -------------------------------------------------------------------------*/
  7.  
  8. #include "sphigslocal.h"
  9.  
  10. #include "MAT3vec.proto.h"
  11.  
  12. /* --------------------------  Static Routines    ---------------------------- */
  13.  
  14. /* -------------------------  Internal Routines  --------------------------- */
  15.  
  16. /* --------------------------  Public Routines    ---------------------------- */
  17.  
  18. /*
  19.  * Multiplies a vector by a matrix, setting the result vector.
  20.  * It assumes all homogeneous coordinates are 1.
  21.  * The two vectors involved may be the same.
  22.  */
  23.  
  24. void
  25. MAT3mult_vec(MAT3vec result_vec, MAT3vec vec, MAT3mat mat)
  26. {
  27.    MAT3vec        tempvec;
  28.    register double    *temp = tempvec;
  29.  
  30.    temp[0] =    vec[0] * mat[0][0] + vec[1] * mat[1][0] +
  31.         vec[2] * mat[2][0] +          mat[3][0];
  32.    temp[1] =    vec[0] * mat[0][1] + vec[1] * mat[1][1] +
  33.         vec[2] * mat[2][1] +          mat[3][1];
  34.    temp[2] =    vec[0] * mat[0][2] + vec[1] * mat[1][2] +
  35.         vec[2] * mat[2][2] +          mat[3][2];
  36.  
  37.    MAT3_COPY_VEC(result_vec, temp);
  38. }
  39.  
  40. /*
  41.  * Multiplies a vector of size 4 by a matrix, setting the result vector.
  42.  * The fourth element of the vector is the homogeneous coordinate, which
  43.  * may or may not be 1.  If the "normalize" parameter is TRUE, then the
  44.  * result vector will be normalized so that the homogeneous coordinate is 1.
  45.  * The two vectors involved may be the same.
  46.  * This returns zero if the vector was to be normalized, but couldn't be.
  47.  */
  48.  
  49. int
  50. MAT3mult_hvec(MAT3hvec result_vec, MAT3hvec vec, MAT3mat mat, int normalize)
  51. {
  52.    MAT3hvec             tempvec;
  53.    double        norm_fac;
  54.    register double    *temp = tempvec;
  55.    register int     ret = TRUE;
  56.  
  57.    temp[0] =    vec[0] * mat[0][0] + vec[1] * mat[1][0] +
  58.         vec[2] * mat[2][0] + vec[3] * mat[3][0];
  59.    temp[1] =    vec[0] * mat[0][1] + vec[1] * mat[1][1] +
  60.         vec[2] * mat[2][1] + vec[3] * mat[3][1];
  61.    temp[2] =    vec[0] * mat[0][2] + vec[1] * mat[1][2] +
  62.         vec[2] * mat[2][2] + vec[3] * mat[3][2];
  63.    temp[3] =    vec[0] * mat[0][3] + vec[1] * mat[1][3] +
  64.         vec[2] * mat[2][3] + vec[3] * mat[3][3];
  65.  
  66.    /* Normalize if asked for, possible, and necessary */
  67.    if (normalize) {
  68.       if (MAT3_IS_ZERO(temp[3])) {
  69. #ifndef THINK_C
  70.      fprintf (stderr,
  71.           "Can't normalize vector: homogeneous coordinate is 0");
  72. #endif
  73.      ret = FALSE;
  74.       }
  75.       else {
  76.      norm_fac = 1.0 / temp[3];
  77.      MAT3_SCALE_VEC(result_vec, temp, norm_fac);
  78.      result_vec[3] = 1.0;
  79.       }
  80.    }
  81.    else MAT3_COPY_HVEC(result_vec, temp);
  82.  
  83.    return(ret);
  84. }
  85.  
  86. /*
  87.  * Sets the first vector to be the cross-product of the last two vectors.
  88.  */
  89.  
  90. void
  91. MAT3cross_product(MAT3vec result_vec, MAT3vec vec1, MAT3vec vec2)
  92. {
  93.    MAT3vec        tempvec;
  94.    register double    *temp = tempvec;
  95.  
  96.    temp[0] = vec1[1] * vec2[2] - vec1[2] * vec2[1];
  97.    temp[1] = vec1[2] * vec2[0] - vec1[0] * vec2[2];
  98.    temp[2] = vec1[0] * vec2[1] - vec1[1] * vec2[0];
  99.  
  100.    MAT3_COPY_VEC(result_vec, temp);
  101. }
  102.  
  103. /*
  104.  * Finds a vector perpendicular to vec and stores it in result_vec.
  105.  * Method:  take any vector (we use <0,1,0>) and subtract the
  106.  * portion of it pointing in the vec direction.  This doesn't
  107.  * work if vec IS <0,1,0> or is very near it.  So if this is
  108.  * the case, use <0,0,1> instead.
  109.  * If "is_unit" is TRUE, the given vector is assumed to be unit length.
  110.  */
  111.  
  112. #define SELECT    .7071    /* selection constant (roughly .5*sqrt(2) */
  113.  
  114. void
  115. MAT3perp_vec(MAT3vec result_vec, MAT3vec vec, int is_unit)
  116. {
  117.    MAT3vec    norm;
  118.    double    dot;
  119.  
  120.    MAT3_SET_VEC(result_vec, 0.0, 1.0, 0.0);
  121.  
  122.    MAT3_COPY_VEC(norm, vec);
  123.  
  124.    if (! is_unit) MAT3_NORMALIZE_VEC(norm, dot);
  125.  
  126.    /* See if vector is too close to <0,1,0>.  If so, use <0,0,1> */
  127.    if ((dot = MAT3_DOT_PRODUCT(norm, result_vec)) > SELECT || dot < -SELECT) {
  128.       result_vec[1] = 0.0;
  129.       result_vec[2] = 1.0;
  130.       dot = MAT3_DOT_PRODUCT(norm, result_vec);
  131.    }
  132.  
  133.    /* Subtract off non-perpendicular part */
  134.    result_vec[0] -= dot * norm[0];
  135.    result_vec[1] -= dot * norm[1];
  136.    result_vec[2] -= dot * norm[2];
  137.  
  138.    /* Make result unit length */
  139.    MAT3_NORMALIZE_VEC(result_vec, dot);
  140. }
  141.